package com.mani.geotag;

import java.util.ArrayList;
import java.util.List;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.RemoteViews;

import com.mani.geotag.R;
import com.mani.geotag.GetMapTask.MapDownloadedCallback;
import com.mani.geotag.LocationIdentifier.LocationIdentifierCallBack;

public class MapService extends Service implements LocationIdentifierCallBack,MapDownloadedCallback{
	private AppWidgetManager mAppWidgetManager;
	LocationIdentifier mLocationIdentifier;	
	GetMapTask mfetchMap;
	ArrayList<AppWidgetItem> appWidgetsList;
	ArrayList<AppWidgetItem> pendingAppWidgetsList;
	Geocoder mReverseGeoCoder;
	Context mContext;
	int currentAppWidgetId;
	Object mlock = new Object();
	
	private final int NO_MATCH = -102;
	private final int DELETE_ID = -100;
	private final int ENABLED_ID = -101;
	private final int UPDATE_ID = -103;
	private final int TRYAGAIN_ID = -104;
	
	TelephonyManager tm;
	
	public static final String PREFS_NAME = "LocalguideWidgetPrefs";
	
	class AppWidgetItem {
		int AppWidgetId;
		int appWidgetType;
		boolean isLocation_scanning= true;
	}
    BroadcastReceiver mNetworkStateIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(
                    ConnectivityManager.CONNECTIVITY_ACTION)) {

	            if(checkInternetConnection() == true)
	            {
					// Some other widget instance is still waiting for its current location
					if(mLocationIdentifier.isSearchingLocation() == false )
					{
						mLocationIdentifier.getLocation();
					}
					for(int i =0;i< pendingAppWidgetsList.size();i++)
					{
						AppWidgetItem item = pendingAppWidgetsList.get(i);
						appWidgetsList.add(item);
					}
					
					pendingAppWidgetsList.clear();

	            }
            } else if(Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
            	//Stop listening for cell change listener.
            	tm.listen(phoneStateListener, 0);
            	
            } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
            	// Start listening for cell change listener
            	int events = PhoneStateListener.LISTEN_CELL_LOCATION;
           		tm.listen(phoneStateListener, events);
            }
        }
    };
	
	public void onCreate()
	{
		mAppWidgetManager = AppWidgetManager.getInstance(this);
		mLocationIdentifier = new LocationIdentifier (this.getApplicationContext(),this);
		mfetchMap = new GetMapTask(this);
		tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
	    int events = PhoneStateListener.LISTEN_CELL_LOCATION ;
	    tm.listen(phoneStateListener, events);
	    mReverseGeoCoder = new Geocoder(getApplicationContext());
	    mContext = this.getApplicationContext();
	    appWidgetsList = new ArrayList<AppWidgetItem>();
	    pendingAppWidgetsList = new ArrayList<AppWidgetItem>();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_SCREEN_ON);
        mContext.registerReceiver(mNetworkStateIntentReceiver, filter);
	}
	
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		if(intent !=null)
		{
			if (intent.getIntExtra("appwidgetid", NO_MATCH) == UPDATE_ID)
			{
				
				int updateAppId = intent.getIntExtra("updateAppWidgetId", 0);
				for(int i=0;i<appWidgetsList.size();i++)
				{
					if(updateAppId == appWidgetsList.get(i).AppWidgetId)
					{
						if(appWidgetsList.get(i).isLocation_scanning == true) {
							appWidgetsList.get(i).isLocation_scanning =false;
							udateMovmentDetection(i);
						}else {
							appWidgetsList.get(i).isLocation_scanning = true;
							udateMovmentDetection(i);
						}
						break;
					}
				}
			}
			else if(intent.getIntExtra("appwidgetid", NO_MATCH) == DELETE_ID)
			{
				synchronized(mlock) {
					// Get the delete appWidget id and remove it from the list.
					int deleteAppId = intent.getIntExtra("deleteAppWidgetId", 0);
					
					//Delete from the appWidgetList
					int i=0;
					for(i=0;i<appWidgetsList.size();i++)
					{
						if(deleteAppId == appWidgetsList.get(i).AppWidgetId)
						{
							appWidgetsList.remove(i);
							break;
						}
					}
				}
				if(appWidgetsList.size() == 0) {
					mLocationIdentifier.stopRequest();
					this.stopSelf();
				}
				
			} 
			else if (intent.getIntExtra("appwidgetid", NO_MATCH) == TRYAGAIN_ID)
			{
				
				int AppId = intent.getIntExtra("AppWidgetId", 0);
				int i=0;
				for(i=0;i<appWidgetsList.size();i++)
				{
					if(AppId == appWidgetsList.get(i).AppWidgetId)
					{
						if(appWidgetsList.get(i).isLocation_scanning == true) {
							// Some other widget instance is still waiting for its current location
							if(mLocationIdentifier.isSearchingLocation() == false )
							{
								mLocationIdentifier.getLocation();
							}
							
							// Update the view with "Finding the location...."
					   		RemoteViews view = new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout);
					   		if(checkInternetConnection() == true)
					   		{
					   			view.setTextViewText(R.id.textupdate,mContext.getString(R.string.find_location) );
					   			
					   		} else  {
					   			view.setTextViewText(R.id.textupdate, mContext.getString(R.string.enable_internet));
					   		}
							mAppWidgetManager.updateAppWidget(AppId, view);
							break;
						}
					}
				}

			}
			else if(intent.getIntExtra("appwidgetid", NO_MATCH) != ENABLED_ID){
				// Some other widget instance is still waiting for its current location
				if(mLocationIdentifier.isSearchingLocation() == false )
				{
					mLocationIdentifier.getLocation();
				}
				
				// Update the view with "Finding the location...."
				
		   		RemoteViews view = new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout1);
		   		if(checkInternetConnection() == true)
		   		{
		   			view.setTextViewText(R.id.textupdate, mContext.getString(R.string.find_location));
		   			
		   		}
		   		else {
		   			view.setTextViewText(R.id.textupdate, mContext.getString(R.string.enable_internet));
		   		}
				
				mAppWidgetManager.updateAppWidget(intent.getIntExtra("appwidgetid", 0), view);
		   		AppWidgetItem item = new AppWidgetItem();
				item.AppWidgetId = intent.getIntExtra("appwidgetid", 0); 
				item.appWidgetType = intent.getIntExtra("appwidgettype", 1);
		   		if(checkInternetConnection() == false)
		   		{
		   			pendingAppWidgetsList.add(item);
		   		}
		   		else
		   		{
		   			appWidgetsList.add(item);
		   		}
			}
		}
		return START_STICKY;
	}
	
	
    public IBinder onBind(Intent intent) {
        return null;
    }
	private boolean checkInternetConnection() {

		ConnectivityManager conMgr = (ConnectivityManager) mContext.getSystemService (mContext.CONNECTIVITY_SERVICE);

		// ARE WE CONNECTED TO THE NET

		if (conMgr.getActiveNetworkInfo() != null
		&& conMgr.getActiveNetworkInfo().isAvailable()
		&& conMgr.getActiveNetworkInfo().isConnected()) {
			return true;
		} else {
			return false;
		}

	} 
	public void settingsDisabled() {
		   
		   
	}	
	String mLocation;
	double mLatitude;
	double mLongitude;
	public void gotLocation(Location location)
	{
		if(location !=null) {
		
		try{
			// Use the rever Geo coder to conver lat and long to a valid location string.
			List<Address> mAddressList = mReverseGeoCoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
		    mLatitude = location.getLatitude();
		    mLongitude = location.getLongitude();
		    
			if (mAddressList.size()> 0){
			
					String  currlocation = mContext.getString(R.string.location)+mAddressList.get(0).getAddressLine(0)+","+mAddressList.get(0).getCountryName();
					currlocation+="\n\n";
					currlocation+=mContext.getString(R.string.loading_map);

					RemoteViews	view= new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout1);
					view.setTextViewText(R.id.textupdate, currlocation);
					
					mLocation = mAddressList.get(0).getAddressLine(0)+","+mAddressList.get(0).getCountryName();
					for(int i =0;i<appWidgetsList.size();i++)
					{
						if(appWidgetsList.get(i).isLocation_scanning == true) {
		                	mAppWidgetManager.updateAppWidget(appWidgetsList.get(i).AppWidgetId, view);
						}
					}
					mfetchMap.fetchMap(location.getLatitude(),location.getLongitude());
			  }
			else
			{
				RemoteViews	view= new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout1);
				view.setTextViewText(R.id.textupdate, mContext.getString(R.string.no_location));
				
				mLocation = mAddressList.get(0).getAddressLine(0)+","+mAddressList.get(0).getCountryName();
				for(int i =0;i<appWidgetsList.size();i++)
				{
					if(appWidgetsList.get(i).isLocation_scanning == true) {
	                	mAppWidgetManager.updateAppWidget(appWidgetsList.get(i).AppWidgetId, view);
					}
				}

			}
		} catch(Exception e) {
			RemoteViews	view= new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationerror);
			view.setTextViewText(R.id.textupdate, mContext.getString(R.string.reversegeo_error));
			
			for(int i =0;i<appWidgetsList.size();i++)
			{
				if(appWidgetsList.get(i).isLocation_scanning == true) {
					Intent serviceIntent = new Intent(mContext, MapService.class);
					serviceIntent.putExtra("updateAppWidgetId", appWidgetsList.get(i).AppWidgetId);
					serviceIntent.putExtra("appwidgetid", TRYAGAIN_ID);
					PendingIntent pendingIntent = PendingIntent.getService(mContext,
			                i, serviceIntent,  PendingIntent.FLAG_UPDATE_CURRENT);
					view.setOnClickPendingIntent(R.id.tryagain, pendingIntent);
	                mAppWidgetManager.updateAppWidget(appWidgetsList.get(i).AppWidgetId, view);
				}
			}
		}
	   }
	}
	
	public void onMapDownlaoded() {
		
		RemoteViews	view= new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout);
		RemoteViews	view1= new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout2x2);
		view.setTextViewText(R.id.textupdate, mLocation);
		view1.setTextViewText(R.id.textupdate, mLocation);

        
		Intent intent = new Intent();
		intent.putExtra("location", mLocation);
		intent.putExtra("latitude", mLatitude);
		intent.putExtra("longitude", mLongitude);
		intent.setClass(mContext, CircularActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
                0, intent,  PendingIntent.FLAG_UPDATE_CURRENT);

		for(int i =0;i<appWidgetsList.size();i++)
		{
			Intent serviceIntent = new Intent(mContext, MapService.class);
			serviceIntent.putExtra("updateAppWidgetId", appWidgetsList.get(i).AppWidgetId);
			serviceIntent.putExtra("appwidgetid", UPDATE_ID);
			PendingIntent pendingIntent1 = PendingIntent.getService(mContext,
	                i, serviceIntent,  PendingIntent.FLAG_UPDATE_CURRENT);

				if(appWidgetsList.get(i).appWidgetType == 1 ) {
					view1.setImageViewBitmap(R.id.map, mfetchMap.mBitmap2x2);
	                view1.setOnClickPendingIntent(R.id.map, pendingIntent);
	                view1.setOnClickPendingIntent(R.id.setting, pendingIntent1);
	                if(appWidgetsList.get(i).isLocation_scanning == true) {
	                	view1.setTextViewText(R.id.setting, "ON");    
	                	mAppWidgetManager.updateAppWidget(appWidgetsList.get(i).AppWidgetId, view1);
	                }
					
			    }else {
					view.setImageViewBitmap(R.id.map, mfetchMap.mBitmap4x2);
					view.setOnClickPendingIntent(R.id.map, pendingIntent);
					view.setOnClickPendingIntent(R.id.setting, pendingIntent1);
	                if(appWidgetsList.get(i).isLocation_scanning == true) {
	                	view.setTextViewText(R.id.setting, "ON");    	
	                	mAppWidgetManager.updateAppWidget(appWidgetsList.get(i).AppWidgetId, view);
	                } 
				}
		}
	}
	public void udateMovmentDetection(int position) {
		RemoteViews view = null;
		if(appWidgetsList.get(position).appWidgetType == 1 ) {
			view = new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout2x2);
		} else if(appWidgetsList.get(position).appWidgetType == 2) {
			view = new RemoteViews(getApplicationContext().getPackageName(),R.layout.findlocationlayout);
		}

		view.setTextViewText(R.id.textupdate, mLocation);
        
		Intent intent = new Intent();
		intent.putExtra("location", mLocation);
		intent.putExtra("latitude", mLatitude);
		intent.putExtra("longitude", mLongitude);
		intent.setClass(mContext, CircularActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
                0, intent,  PendingIntent.FLAG_UPDATE_CURRENT);

        Intent serviceIntent = new Intent(mContext, MapService.class);
		serviceIntent.putExtra("updateAppWidgetId", appWidgetsList.get(position).AppWidgetId);
		serviceIntent.putExtra("appwidgetid", UPDATE_ID);
		PendingIntent pendingIntent1 = PendingIntent.getService(mContext,
                position, serviceIntent,  PendingIntent.FLAG_UPDATE_CURRENT);
        
		if(appWidgetsList.get(position).appWidgetType == 1 ) {
			view.setImageViewBitmap(R.id.map, mfetchMap.mBitmap2x2);
            view.setOnClickPendingIntent(R.id.map, pendingIntent);
            view.setOnClickPendingIntent(R.id.setting, pendingIntent1);
            if(appWidgetsList.get(position).isLocation_scanning == true) {
            	view.setTextViewText(R.id.setting, "ON");    	
            } else {
            	view.setTextViewText(R.id.setting, "OFF");
            }
			mAppWidgetManager.updateAppWidget(appWidgetsList.get(position).AppWidgetId, view);
	    }else {
			view.setImageViewBitmap(R.id.map, mfetchMap.mBitmap4x2);
			view.setOnClickPendingIntent(R.id.map, pendingIntent);
			view.setOnClickPendingIntent(R.id.setting, pendingIntent1);
            if(appWidgetsList.get(position).isLocation_scanning == true) {
            	view.setTextViewText(R.id.setting, "ON");    	
            } else {
            	view.setTextViewText(R.id.setting, "OFF");
            }
			mAppWidgetManager.updateAppWidget(appWidgetsList.get(position).AppWidgetId, view);
		}
	}
	
    private final PhoneStateListener phoneStateListener = new PhoneStateListener(){

		@Override
        public void onCellLocationChanged(CellLocation location)
        {
                // Get the current location
        		if(mLocationIdentifier.isSearchingLocation() == false )
        		{
        			boolean itemfound = false;
        			//If any one of the app widget has location scanning set to true, query for location will be
        			// triggered. Else not triggered.
    				for(int i=0;i<appWidgetsList.size();i++)
    				{
    						if(appWidgetsList.get(i).isLocation_scanning == true) {
    							itemfound = true;
    							break;
    						}
    				}
    				if(itemfound == true)
    					mLocationIdentifier.getLocation();
        		}
                super.onCellLocationChanged(location);
        }
    };
}

